/**
*
* Copyright 2015 Kamran Zafar
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.xeustechnologies.jcl.spring;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Node;
import org.xeustechnologies.jcl.JclObjectFactory;
import org.xeustechnologies.jcl.exception.JclException;
/**
* @author Kamran Zafar
*
*/
public class JclBeanDefinitionDecorator implements BeanDefinitionDecorator {
private static final String JCL_REF = "ref";
private static final String JCL_FACTORY = "jcl-factory-" + UUID.randomUUID();
private static final String JCL_FACTORY_METHOD = "create";
private static final String JCL_FACTORY_CONSTRUCTOR = "getInstance";
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder holder, ParserContext parserContext) {
String jclRef = node.getAttributes().getNamedItem( JCL_REF ).getNodeValue();
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setFactoryBeanName( JCL_FACTORY );
bd.setFactoryMethodName( JCL_FACTORY_METHOD );
bd.setConstructorArgumentValues( holder.getBeanDefinition().getConstructorArgumentValues() );
bd.setPropertyValues( holder.getBeanDefinition().getPropertyValues() );
bd.getConstructorArgumentValues().addIndexedArgumentValue( 0,
new ConstructorArgumentValues.ValueHolder( parserContext.getRegistry().getBeanDefinition( jclRef ) ) );
bd.getConstructorArgumentValues().addIndexedArgumentValue( 1,
new ConstructorArgumentValues.ValueHolder( holder.getBeanDefinition().getBeanClassName() ) );
BeanDefinitionHolder newHolder = new BeanDefinitionHolder( bd, holder.getBeanName() );
createDependencyOnJcl( node, newHolder, parserContext );
return newHolder;
}
@SuppressWarnings("unchecked")
private void createDependencyOnJcl(Node node, BeanDefinitionHolder holder, ParserContext parserContext) {
AbstractBeanDefinition definition = ( (AbstractBeanDefinition) holder.getBeanDefinition() );
String jclRef = node.getAttributes().getNamedItem( JCL_REF ).getNodeValue();
if( !parserContext.getRegistry().containsBeanDefinition( JCL_FACTORY ) ) {
BeanDefinitionBuilder initializer = BeanDefinitionBuilder.rootBeanDefinition( JclObjectFactory.class,
JCL_FACTORY_CONSTRUCTOR );
parserContext.getRegistry().registerBeanDefinition( JCL_FACTORY, initializer.getBeanDefinition() );
}
if( parserContext.getRegistry().containsBeanDefinition( jclRef ) ) {
String[] dependsOn = definition.getDependsOn();
if( dependsOn == null ) {
dependsOn = new String[] { jclRef, JCL_FACTORY };
} else {
List dependencies = new ArrayList( Arrays.asList( dependsOn ) );
dependencies.add( jclRef );
dependencies.add( JCL_FACTORY );
dependsOn = (String[]) dependencies.toArray( new String[0] );
}
definition.setDependsOn( dependsOn );
} else
throw new JclException( "JCL Bean definition " + jclRef + "not found" );
}
}